/**
 * 
 * @TODO
 * - send data to url
 * - POST or GET pr FILE options
 *  
 * ***/
package Avocado.util {
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.external.ExternalInterface;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;

	public class AvocadoJsonLoader extends EventDispatcher {

		public var result:Object;
		public var rawResult:String;

		private var request:URLRequest;
		private var loader:URLLoader;
		
		private var _debug:Boolean = new Boolean(false);

		public function AvocadoJsonLoader(urlString:String, sendData:URLVariables=null, sendMethod:String='POST', target:IEventDispatcher=null) {
			super(target);
			
			request = new URLRequest(urlString);
			
			if (sendData) {
				request.data = sendData;
			}
			
			if (debug == true) {
				if (ExternalInterface.available) {
					try { ExternalInterface.call('console.debug', urlString); } catch (err:Error) { trace(err); }
				}
				// trace(urlString);
			}
			
			if (sendMethod) {
				switch (sendMethod) {
					case 'GET' :
						request.method = URLRequestMethod.GET;
						break;
					case 'POST' :
						request.method = URLRequestMethod.POST;
						break;
				}
			}

			loader = new URLLoader(request);
			loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatus);
			loader.addEventListener(IOErrorEvent.IO_ERROR, loaderError);
			loader.addEventListener(ProgressEvent.PROGRESS, loaderProgress);
			loader.addEventListener(Event.COMPLETE, jsonComplete);
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityError);
			loader.load(request);
		}
		
		
		/**
		 * 
		 * ***/
		public function get debug():Boolean {
			return _debug;
		}

		/**
		 * 
		 * ***/
		public function set debug(value:Boolean):void {
			_debug = value;
		}

		
		

		/**
		 * 
		 * ***/
		public function load(_urlString:String):AvocadoJsonLoader{
			return new AvocadoJsonLoader(_urlString);
		} 

		/**
		 * 
		 * ***/
		private function loaderProgress(e:ProgressEvent):void{
			this.dispatchEvent(new ProgressEvent(e));
			if (debug == true) {
				if (ExternalInterface.available) {
					try { ExternalInterface.call('console.debug', e); } catch (err:Error) { trace(err); }
				}
				// trace(e);
			}
		}

		/**
		 * 
		 * ***/
		private function loaderError(e:IOErrorEvent):void{
			this.dispatchEvent(e);
			if (debug == true) {
				if (ExternalInterface.available) {
					try { ExternalInterface.call('console.debug', e); } catch (err:Error) { trace(err); }
				}
				// trace(e);
			}
		}

		/**
		 * 
		 * ***/
		private function httpStatus(e:HTTPStatusEvent):void{
			this.dispatchEvent(e);
			if (debug == true) {
				if (ExternalInterface.available) {
					try { ExternalInterface.call('console.debug', e); } catch (err:Error) { trace(err); }
				}
				// trace(e);
			}
		}

		/**
		 * 
		 * ***/
		private function securityError(e:SecurityErrorEvent):void{
			this.dispatchEvent(e);
			if (debug == true) {
				if (ExternalInterface.available) {
					ExternalInterface.call('console.debug', e);
				}
				// trace(e);
			}
		}

		/**
		 * 
		 * ***/
		private function jsonComplete(e:Event=null):void {
			loader.removeEventListener(ProgressEvent.PROGRESS, loaderProgress);
			loader.removeEventListener(Event.COMPLETE, jsonComplete);
			loader.removeEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatus);
			loader.removeEventListener(IOErrorEvent.IO_ERROR, loaderError);
			
			rawResult = new String(e.target.data);

			if (e.target != null){
				var jsonString:String = new String(e.target.data);
				try {
					result = new JSONObject(jsonString);
					this.dispatchEvent(new Event(Event.COMPLETE));
				} catch (err:Error) {
					var ioError:IOErrorEvent = new IOErrorEvent(IOErrorEvent.IO_ERROR);
					ioError.text = err.toString();
					this.dispatchEvent(ioError);
				}
			} else {
				this.dispatchEvent(new IOErrorEvent(IOErrorEvent.NETWORK_ERROR)); 
			}
			
		}


		
	}
}